/*===============================================
 *   文件名称：server.c
 *   创 建 者：
 *   创建日期：2024年12月10日
 *   描    述：
 ================================================*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include "Smarthome.h"

int main(int argc, char *argv[])
{
    if (argc != 2) 
    {
        printf("Usage:\n\t%s port\n", argv[0]);
        exit(1);
    }

    uint16_t port = atoi(argv[1]);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket");
        return -1;
    }

    printf("socket success\n");

    int a = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &a, sizeof(a)) < 0)
    {
        perror("setsockopt");
        close(sockfd);
        return -1;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    socklen_t addrlen = sizeof(addr);

    if (bind(sockfd, (const struct sockaddr *)&addr, addrlen) < 0)
    {
        perror("bind");
        close(sockfd);
        return -1;
    }

    printf("bind success\n");

    if (listen(sockfd, 5) < 0)
    {
        perror("listen");
        close(sockfd);
        return -1;
    }

    printf("listen success\n");

    int camera_fd = camera_init("/dev/video0");
    if (camera_fd < 0)
    {
        printf("----camera_init error\n");
        close(sockfd);
        return -1;
    }
    camera_start(camera_fd);

    while (1)
    {
        struct sockaddr_in caddr;
        socklen_t caddrlen = sizeof(caddr);
        int connfd = accept(sockfd, (struct sockaddr *)&caddr, &caddrlen);

        if (connfd < 0)
        {
            perror("accept");
            continue;
        }

        printf("client connect success\n");

        while (1)
        {
            char *pic_buf;
            int length;
            int bytes_written;
            
            if (camera_get(camera_fd, &pic_buf, &length) < 0) {
                perror("camera_get");
                break;
            }

            char len[8] = {0};
            sprintf(len, "%d", length);
            
            bytes_written = write(connfd, len, sizeof(len));
            if (bytes_written <= 0) {
                perror("write len");
                break;
            }

            bytes_written = write(connfd, pic_buf, length);
            if (bytes_written <= 0) {
                perror("write pic_buf");
                break;
            }

            camera_input(camera_fd);
        }
        
        close(connfd);
        printf("client disconnected\n");
    }

    close(camera_fd);
    close(sockfd);

    return 0;
}